home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / RAWCONS.C < prev    next >
C/C++ Source or Header  |  1997-08-18  |  9KB  |  441 lines

  1. #ifdef UNIX
  2. /*
  3.  * A "raw console" session manager.  This is sort of a high-speed version of
  4.  * "curses" --- but uses the current terminal type, instead of either a dumb
  5.  * terminal or ANSI X3.64 emulation.  It's a little smarter than "dumb", but
  6.  * not much.
  7.  */
  8.  
  9. /*lint -save -e10 -e19 -e36 -e18 -e652 -e659 */
  10. #ifdef HAVE_NCURSES_H
  11. #include <ncurses.h>
  12. #else
  13. #include <curses.h>
  14. #endif
  15. #undef FALSE
  16. #undef TRUE
  17. #include "global.h"
  18. #include "hardware.h"
  19. #include "proc.h"
  20. /*lint -restore */
  21. #undef tputs
  22.  
  23. #if !defined(_lint)
  24. static char rcsid[] OPTIONAL = "$Id: rawcons.c,v 1.18 1997/08/19 01:19:22 root Exp root $";
  25. #endif
  26.  
  27. #ifdef SM_RAW
  28. #include <term.h>
  29.  
  30. /*
  31.  * ought to share these... they're going to be identical between raw and curses
  32.  */
  33.  
  34. struct keytrie
  35. {
  36.     enum {KT_DEF, KT_TRIE, KT_TVAL, KT_VAL} kt_type; /* type of entry */
  37.     int kt_tval;        /* if a TVAL, the timed-out value */
  38.     union
  39.     {
  40.     struct keytrie *ktu_trie; /* sub-trie */
  41. #define kt_trie kt_u.ktu_trie
  42.     int ktu_val;        /* value */
  43. #define kt_val kt_u.ktu_val
  44.     } kt_u;
  45. };
  46.  
  47. static struct termios old_tty, new_tty;
  48. static int Suspense, infoed;
  49. static struct keytrie *keys;
  50. static TERMINAL *my_term;
  51.  
  52. static void
  53. key_init(void)
  54. {
  55.     int i;
  56.  
  57.     keys = mallocw(256 * sizeof *keys);
  58.     for (i = 256; i--; )
  59.     {
  60.     keys[i].kt_type = KT_DEF;
  61.     keys[i].kt_val = i;
  62.     }
  63. }
  64.  
  65. static void
  66. key_add(const char *str, int val)
  67. {
  68.     const char *old;
  69.     struct keytrie *t;
  70.     int c, i;
  71.  
  72.     /*
  73.      * Follow the trie until we get to the right subtrie for the string, then
  74.      * add the value.  If we hit a KT_DEF, expand the trie.  If we hit a KT_VAL
  75.      * change it to a KT_TVAL, which times out as a KT_VAL but continues as a
  76.      * KT_TRIE.  If given a value for a KT_TRIE, change it to a KT_TVAL.
  77.      */
  78.     if (!str || !*str)
  79.     return;            /* no key to define */
  80.     old = str;
  81.     t = keys;
  82.     while (str[1])
  83.     {
  84.     c = uchar(*str++);
  85.     if (t[c].kt_type != KT_TRIE)
  86.     {
  87.         if (t[c].kt_type == KT_DEF)
  88.         t[c].kt_type = KT_TRIE;
  89.         else
  90.         {
  91.         t[c].kt_type = KT_TVAL;
  92.         t[c].kt_tval = t[c].kt_val;
  93.         }
  94.         t[c].kt_trie = mallocw(256 * sizeof (struct keytrie));
  95.         for (i = 256; i--; )
  96.         {
  97.         t[c].kt_trie[i].kt_type = KT_DEF;
  98.         t[c].kt_trie[i].kt_val = i;
  99.         }
  100.     }
  101.     t = t[c].kt_trie;
  102.     }
  103.     c = uchar(*str);
  104.     if (t[c].kt_type == KT_TRIE)
  105.     {
  106.     t[c].kt_type = KT_TVAL;
  107.     t[c].kt_tval = val;
  108.     }
  109.     else if (t[c].kt_type == KT_DEF)
  110.     {
  111.     t[c].kt_type = KT_VAL;
  112.     t[c].kt_val = val;
  113.     }
  114. }
  115.  
  116. static int
  117. raw_init(const struct sessmgr_sw *sm)
  118. {
  119.     extern int Numrows, Numcols;
  120.  
  121.     if (infoed)
  122.     set_curterm(my_term);
  123.     else
  124.     {
  125.     /*
  126.      * By rights we should use curses' setup, but then it becomes harder
  127.      * to configure either out.  Waste a little memory for now; it's not
  128.      * going to be much more than the size of the terminfo file, which
  129.      * is itself rarely more than 1.5K.
  130.      */
  131.     setupterm(0, 1, 0);
  132.     my_term = cur_term;
  133.     /* load keytrie */
  134.     key_init();
  135.     key_add(key_down, DNARROW);
  136.     key_add(key_f1, -3);
  137.     key_add(key_f2, -4);
  138.     key_add(key_f3, -5);
  139.     key_add(key_f4, -6);
  140.     key_add(key_f5, -7);
  141.     key_add(key_f6, -8);
  142.     key_add(key_f7, -9);
  143.     key_add(key_f8, -10);
  144.     key_add(key_f9, -11);
  145.     key_add(key_f10, -2);
  146.     key_add(key_left, LTARROW);
  147.     key_add(key_right, RTARROW);
  148.     key_add(key_up, UPARROW);
  149.     key_add("\177", '\b');    /* so DEL behaves as BS */
  150.     infoed = 1;
  151.     }
  152.     if (tcgetattr(0, &old_tty) == -1)
  153.     return 0;
  154.     new_tty = old_tty;
  155.     new_tty.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  156.     new_tty.c_cc[VMIN] = 1;
  157.     new_tty.c_cc[VTIME] = 0;
  158.     tcsetattr(0, TCSADRAIN, &new_tty);
  159.     Numrows = lines;
  160.     Numcols = columns;
  161.     putp(enter_ca_mode);
  162.     return 1;
  163. }
  164.  
  165. static void
  166. raw_end(const struct sessmgr_sw *sm)
  167. {
  168.     if (!Suspense)
  169.     {
  170.     putp(exit_ca_mode);
  171.     tcsetattr(0, TCSADRAIN, &old_tty);
  172.     }
  173. }
  174.  
  175. static void
  176. raw_suspend(const struct sessmgr_sw *sm)
  177. {
  178.     if (!Suspense++)
  179.     {
  180.     putp(exit_ca_mode);
  181.     fflush(stdout);
  182.     tcsetattr(0, TCSADRAIN, &old_tty);
  183.     }
  184. }
  185.  
  186. static void
  187. raw_resume(const struct sessmgr_sw *sm)
  188. {
  189.     extern int Numrows, Numcols;
  190.  
  191.     if (!--Suspense)
  192.     {
  193.     tcsetattr(0, TCSADRAIN, &new_tty);
  194.     set_curterm(my_term);
  195.     Numrows = lines;
  196.     Numcols = columns;
  197.     putp(enter_ca_mode);
  198.     }
  199. }
  200.  
  201. static int
  202. raw_swap(const struct sessmgr_sw *sm, void *old, void *new)
  203. {
  204.     int c;
  205.  
  206.     if (old && new)
  207.     {
  208.     c = (int) new - 1;
  209.     putp(clear_screen);
  210.     printf(">>> switching to session %d", c);
  211.     if (Sessions[c].name && *Sessions[c].name)
  212.         printf(": %s", Sessions[c].name);
  213.     else if (Sessions[c].proc->name && *Sessions[c].proc->name)
  214.         printf(" [%s]", Sessions[c].proc->name);
  215.     printf(" (%s)\n", Sestypes[Sessions[c].type]);
  216.     }
  217.     return 0;            /* only the current session can do output */
  218. }
  219.  
  220. static void
  221. raw_putch(const struct sessmgr_sw *sm, void *dp, int c)
  222. {
  223.     putchar(c);
  224. }
  225.  
  226. static void
  227. raw_clreol(const struct sessmgr_sw *sm, void *dp)
  228. {
  229.     putp(clr_eol);
  230. }
  231.  
  232. static void
  233. raw_flush(const struct sessmgr_sw *sm, void *dp)
  234. {
  235.     if (!Suspense)
  236.     fflush(stdout);
  237. }
  238.  
  239. static void *
  240. raw_create(const struct sessmgr_sw *sm, struct session *sp)
  241. {
  242.     return (void *) (sp - Sessions + 1);
  243. }
  244.  
  245. static void
  246. raw_destroy(const struct sessmgr_sw *sm, void *dp)
  247. {
  248. }
  249.  
  250. static void
  251. raw_clrscr(const struct sessmgr_sw *sm, void *dp)
  252. {
  253.     putp(clear_screen);
  254. }
  255.  
  256. static int
  257. raw_wherex(const struct sessmgr_sw *sm, void *dp)
  258. {
  259.     return -1;
  260. }
  261.  
  262. static int
  263. raw_wherey(const struct sessmgr_sw *sm, void *dp)
  264. {
  265.     return -1;
  266. }
  267.  
  268. static void
  269. raw_window(const struct sessmgr_sw *sm, void *dp, int x1, int y1, int x2,
  270.           int y2)
  271. {
  272. }
  273.  
  274. static void
  275. raw_gotoxy(const struct sessmgr_sw *sm, void *dp, int x, int y)
  276. {
  277.     putp(tparm(cursor_address, y - 1, x - 1));
  278. }
  279.  
  280. static void
  281. raw_high(const struct sessmgr_sw *sm, void *dp)
  282. {
  283.     vidattr(A_REVERSE);
  284. }
  285.  
  286. static void
  287. raw_norm(const struct sessmgr_sw *sm, void *dp)
  288. {
  289.     vidattr(A_NORMAL);
  290. }
  291.  
  292. static void
  293. raw_bground (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
  294. {
  295. }
  296.  
  297. static void
  298. raw_fground (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
  299. {
  300. }
  301.  
  302. static void
  303. raw_txtattr (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
  304. {
  305. }
  306.  
  307. static void
  308. raw_refresh (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
  309. {
  310. }
  311.  
  312. static void
  313. raw_cursor(const struct sessmgr_sw *sm, void *dp, int c)
  314. {
  315.     switch (c)
  316.     {
  317.     case _NOCURSOR:
  318.     putp(cursor_invisible);
  319.     break;
  320.     case _NORMALCURSOR:
  321.     putp(cursor_normal);
  322.     break;
  323.     case _SOLIDCURSOR:
  324.     putp(cursor_visible);
  325.     break;
  326.     }
  327. }
  328.  
  329. /*
  330.  * Same as for curses... probably ought to share them
  331.  */
  332.  
  333. static int
  334. kbchar(int ir)
  335. {
  336.     extern int Keyboard;
  337.     unsigned char ch;
  338.     int i;
  339.  
  340.     if (ir)
  341.     kalarm(500);
  342.     do
  343.     {
  344.     if (kwait(&Keyboard) != 0 && ir)
  345.         return -1;
  346.     }
  347.     while ((i = read(0, &ch, 1)) == 0 || (i == -1 && errno == EWOULDBLOCK));
  348.     kalarm(0);
  349.     if (i < 0)
  350.     {
  351.     tputs("NOS PANIC: Lost keyboard\n");
  352.     where_outta_here(1, "kbchar");
  353.     }
  354.     return ch;
  355. }
  356.  
  357. static int
  358. raw_kbread(const struct sessmgr_sw *sm, void *dp)
  359. {
  360.     static int ungets[10];
  361.     struct keytrie *t;
  362.     static int unget;
  363.     int ungetc[10];
  364.     int c, i, u;
  365.  
  366.     i = 0;
  367.     u = 0;
  368.     if (unget > i)
  369.     c = ungets[i++];
  370.     else
  371.     c = kbchar(0);
  372.     ungetc[u++] = c;
  373.     t = keys;
  374.     while (t[c].kt_type == KT_TRIE || t[c].kt_type == KT_TVAL)
  375.     {
  376.     t = t[c].kt_trie;
  377.     if (unget > i)
  378.         c = ungets[i++];
  379.     else
  380.         c = kbchar(1);
  381.     if (c == -1)
  382.         break;
  383.     ungetc[u++] = c;
  384.     }
  385.     if (t[c].kt_type == KT_VAL)
  386.     {
  387.     u = 0;
  388.     c = t[c].kt_val;
  389.     }
  390.     else if (t[c].kt_type == KT_TVAL)
  391.     {
  392.     u = 0;
  393.     c = t[c].kt_tval;
  394.     }
  395.     while (i < unget)
  396.     ungetc[u++] = ungets[i++];
  397.     if (u)
  398.     {
  399.     c = ungetc[0];
  400.     for (i = u; i; i--)
  401.         ungets[i - 1] = ungetc[i];
  402.     unget = u - 1;
  403.     }
  404.     return c;
  405. }
  406.  
  407. struct sessmgr_sw raw_sessmgr =
  408. {
  409.     "raw",
  410.     SM_STDIO,
  411.     raw_init,
  412.     (char *(*)(const struct sessmgr_sw *, char *)) 0,
  413.     raw_create,
  414.     (char *(*)(const struct sessmgr_sw *, void *, char *)) 0,
  415.     raw_swap,
  416.     raw_putch,
  417.     raw_clreol,
  418.     raw_clrscr,
  419.     raw_wherex,
  420.     raw_wherey,
  421.     raw_window,
  422.     raw_gotoxy,
  423.     raw_high,
  424.     raw_norm,
  425.     raw_bground,
  426.     raw_fground,
  427.     raw_txtattr,
  428.     raw_refresh,
  429.     raw_cursor,
  430.     raw_kbread,
  431.     raw_destroy,
  432.     raw_flush,
  433.     raw_suspend,
  434.     raw_resume,
  435.     raw_end,
  436. };
  437.  
  438. #endif
  439.  
  440. #endif        /* UNIX */
  441.